#ifndef encoders_h
#define encoders_h
/**
 * @defgroup nxbot_encoder ENCODER Library
 * @ingroup nxbot_low_level
 * @code #include <encoders.h> @endcode
 * @brief Encoder library for odometry readings.
 *
 * This module is used to read the %encoders count of the two motors of NXBot. Two timers of the microcontroller ATmega1281 are used, 
 * and are configured as counters. NXBot does not have cuadrature %encoders, that means, we cannot be sure of the direction of the wheels. 
 * That is why an alternate method was used. The desired direction is taken as the real direction of the wheel. That is a naive approximation, 
 * but hoping that the inertia of the robot is not too strong, and that the robot will not be exposed to undesired forces agains its movements, 
 * it is valid.
 * No interrupts are used for constantly reading the %encoders. It is up to the user to do this task. 
 *
 */
/**@{*/
//#include "structures.h"
/**
 * @brief   Constant used to define the behavior of the %encoders. 
 * 
 * When configured as FORWARD, the odometer increments its count with the counts of the encoder.
 */
#define ENC_FORWARD 0

/**
 * @brief   Constant used to define the behavior of the %encoders. 
 * 
 * When configured as REVERSE, the odometer decrements its count with the counts of the encoder.
 */
#define ENC_REVERSE 1

/**
 * @brief   Constant used in encoders_read() function. 
 */
#define ENC_LEFT 		0

/**
 * @brief   Constant used in encoders_read() function. 
 */
#define ENC_RIGHT 	1


/**
 * @brief Read the left odometer.
 *
 * Reads the %encoders count from the left motor, and increments or decrements left odometer count.
 * Counts are in ticks, tick to meter transformation is done in the motors module.
 *
 * @return left odometer count
 * 
 */
unsigned int encoders_readLeft(void);

/**
 * @brief Read the right odometer.
 *
 * Reads the %encoders count from the right motor, and increments or decrements right odometer count.
 * Counts are in ticks, tick to meter transformation is done in the motors module.
 *
 * @return right odometer count
 * 
 */
unsigned int encoders_readRight(void);

/**
 * @brief Read both odometers.
 *
 * This function facilitates the readings for both %encoders, by using functions encoders_getStateRight() and encoders_getStateLeft().
 * Counts are in ticks, tick to meter transformation is done in the motors module.
 *
 * @param enc pointer to integer array where the first position is the value of the left odometer, second position is the value of the right odometer.
 * 
 */
void encoders_readAll(unsigned int *enc[]);

/**
 * @brief Read both odometers.
 *
 * This function facilitates the readings for both %encoders, by using functions encoders_getStateRight() and encoders_getStateLeft().
 * Counts are in ticks, tick to meter transformation is done in the motors module. It exist only to accomplish the standard of a <i>read()</i> function 
 * for each sensor.
 *
 * @param enc Constant to select which odometer will be readed. Use only ENC_LEFT or ENC_RIGHT. If other value is used, 0 is returned.
 * @return odometer count
 * 
 */
unsigned int encoders_read(unsigned char enc);

/**
 * @brief Write predefined value for left encoder.
 *
 * Write a certain value to the left encoder. Normally used to reset the %encoders count, or for the definition of a new robot position.
 * This function is mainly used for resetting the counts and also for implementing an up/down counter (incremental/decremental),
 * behavior which is implemented by the function encoders_setDirection().
 *
 * @param val New tick values for the encoder.
 * 
 */
void encoders_writeLeft(unsigned int val);

/**
 * @brief Write predefined value for right encoder.
 *
 * Write a certain value to the right encoder. Normally used to reset the %encoders count, or for the definition of a new robot position.
 * This function is mainly used for resetting the counts and also for implementing an up/down counter (incremental/decremental),
 * behavior which is implemented by the function encoders_setDirection().
 *
 * @param val New tick values for the encoder.
 * 
 */
void encoders_writeRight(unsigned int val);

/**
 * @brief Write predefined values for the %encoders.
 *
 * Standard function write which is an easy way to write both encoders
 *
 * @param left New tick values for the left encoder.
 * @param right New tick values for the right encoder.
 * 
 */
void encoders_write(unsigned int left,unsigned int right);

/**
 * @brief Inizialisation of %encoders hardware.
 *
 * Configures Timer1 and Timer3 from ATmega1281 microcontroller as counters. The counters will begin the count only when encoders_start() has been
 * called. Otherwise they remain disabled.
 * 
 */
void encoders_init(void);

/**
 * @brief Enables both %encoders.
 * 
 */
void encoders_start(void);

/**
 * @brief Disables both %encoders.
 * 
 * The counting values will not be reset. Use encoders_reset() if you want to reset counts.
 */
void encoders_stop(void);

/**
 * @brief Defines wether the encoder should count backward or forward.
 * 
 * This function is fundamental for counting purposes, due to the lack of cuadrature %encoders. It defines wheter the counts of the %encoders should be
 * forward or backward (i.e. incrementing counts or decrementing counts). The counting direction is determined by the desired direction of the wheel.
 * If the wheel direction is configured as forward, then the count increments over time. When the wheel direction is configured as backward, then the
 * count decrements over time.
 *
 * @param left direction for the left encoder. Use ENC_FORWARD or ENC_REVERSE.
 * @param right direction for the right encoder. Use ENC_FORWARD or ENC_REVERSE
 */
void encoders_setDirection(unsigned char left, unsigned char right);


/**
 * @brief Returns the actual counting direction of the encoders.
 * 
 * Retrieves wether the encoders is counting up or down.
 *
 * @param left pointer to the variable where the left direction will be stored. Posible values are ENC_FORWARD or ENC_REVERSE.
 * @param right pointer to the variable where the right direction will be stored. Posible values are ENC_FORWARD or ENC_REVERSE.
 */
void encoders_getDirection(unsigned char *left, unsigned char *right);
/**
 * @brief Resets right encoder.
 * 
 * Right %encoders count will be reset to zero.
 *
 */
#define encoders_resetRight() encoders_writeRight(0)

/**
 * @brief Resets left encoder.
 * 
 * Left %encoders count will be reset to zero.
 *
 */
#define encoders_resetLeft() encoders_writeLeft(0)

/**
 * @brief Resets both %encoders.
 * 
 * Left and right %encoders counts will be reset to zero.
 *
 */
#define encoders_reset() encoders_write(0,0)

/**@}*/
#endif
